package com.mm.controller.web.user;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.AopLog;
import com.mm.base.annotation.VerifyToken;
import com.mm.util.result.DPage;
import com.mm.util.result.DResult;
import com.mm.domain.user.DRole;
import com.mm.serivce.user.IDRoleService;
import com.mm.vo.web.user.RoleVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色信息表 前端控制器
 * </p>
 *
 * @author JueDream
 * @since 2021-08-04
 */
@Api(value = "/r/v1", tags = {"角色信息"})
@Slf4j
@VerifyToken
@RestController
@RequestMapping("/r/v1")
@AopLog(type = "角色信息", stackTraceOnErr = true)
public class DRoleController {

    private final IDRoleService roleService;

    public DRoleController(IDRoleService roleService) {
        this.roleService = roleService;
    }

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "int", dataTypeClass = Integer.class, name = "page", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "int", dataTypeClass = Integer.class, name = "limit", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "string", dataTypeClass = String.class, name = "roleText", value = "")
    })
    @ApiOperation(value = "角色信息列表查询接口", notes = "", httpMethod = "POST")
    @PostMapping("/queryRolePage")
    public DResult queryRolePage(@RequestParam int page, @RequestParam int limit, @RequestParam(required = false) String roleText){
        Page<DRole> rolePage = roleService.queryRolePage(page, limit, roleText);
        DPage<DRole> roleDPage = DPage.to(rolePage);
        return DResult.of(roleDPage);
    }

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "Map<String, Object>", dataTypeClass = Map.class, name = "map", value = "")
    })
    @ApiOperation(value = "角色信息查询接口", notes = "", httpMethod = "POST")
    @PostMapping("/queryRoleList")
    public DResult queryRoleList(@RequestBody Map<String, Object> map){
        Integer userId = -1;
        if (StrUtil.isNotBlank(map.get("userId").toString())){
            userId = Integer.parseInt(map.get("userId").toString());
        }

        List<RoleVo> roleVos = null;
        if (userId > 0) {
            roleVos = this.mergeRole(roleService.queryRoleList(), roleService.queryRoleList(userId));
        }else{
            roleVos = this.mergeRole(roleService.queryRoleList(), new ArrayList<>());
        }
        return DResult.of(roleVos);
    }


    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "int", dataTypeClass = Integer.class, name = "roleId", value = "")
    })
    @ApiOperation(value = "角色信息查询单个接口", notes = "", httpMethod = "POST")
    @PostMapping("/queryRoleOne")
    public DResult queryRoleOne(@RequestParam Integer roleId){
        return DResult.of(roleService.queryRoleOne(roleId));
    }

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "DRole", dataTypeClass = DRole.class, name = "role", value = "")
    })
    @ApiOperation(value = "角色信息编辑接口", notes = "", httpMethod = "POST")
    @Transactional
    @PostMapping("/saveOrUpdate")
    public DResult saveOrUpdate(@RequestBody DRole role) {
        boolean flag = false;
        if (role.getRoleId() < 0) {
            // 新增
            flag = roleService.save(role);
        } else if (role.getRoleId()  > 0) {
            // 更新
            flag = roleService.updateById(role);
        }
        return DResult.of(flag);
    }

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "int", dataTypeClass = Integer.class, name = "roleId", value = "")
    })
    @ApiOperation(value = "角色信息删除接口", notes = "", httpMethod = "DELETE")
    @DeleteMapping("/delete")
    public DResult delete(@RequestParam Integer roleId){
        boolean flag = false;
        if (roleId > 0) {
            flag = roleService.removeRole(roleId);
        }
        return DResult.of(flag);
    }

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "Map<String, Object>", dataTypeClass = Map.class, name = "map", value = "")
    })
    @ApiOperation(value = "绑定角色菜单接口", notes = "", httpMethod = "POST")
    @PostMapping("/bindAuthMenu")
    public DResult bindAuthMenu(@RequestBody Map<String, Object> map){
        Integer roleId = Integer.parseInt(map.get("roleId").toString());
        List<Integer> pIds = new ArrayList<>();
        String pIdStr = map.get("pIds").toString();
        if (StrUtil.isNotBlank(pIdStr)){
            pIds = Arrays.asList(pIdStr.split(",")).stream()
                    .map(s -> Integer.valueOf(s.trim()))
                    .collect(Collectors.toList());
        }
        // 判断角色是否存在
        if (roleId > 0) {
            DRole role =  roleService.queryRoleOne(roleId);
            if (Objects.isNull(role)){
                return DResult.failed("角色不存在");
            }
            if (roleService.bindAuthMenu(roleId, pIds)) {
                return DResult.success();
            }
        }
        return DResult.failed();
    }

    /**
     * 合并角色数据进行展示
     * @param roleAll
     * @param roleHave
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "List<DRole>", dataTypeClass = List.class, name = "roleAll", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "List<DRole>", dataTypeClass = List.class, name = "roleHave", value = "")
    })
    @ApiOperation(value = "合并角色数据进行展示", notes = "合并角色数据进行展示")
    public List<RoleVo> mergeRole(List<DRole> roleAll, List<DRole> roleHave){
        List<RoleVo> roleVos = new ArrayList<>();
        RoleVo vo = null;
        Map<Integer, DRole> roleHaveMap = new HashMap<>();
        if (roleHave.size() > 0){
            roleHaveMap = roleHave.stream().collect(Collectors.toMap(DRole::getRoleId, role -> role));
        }
        for (DRole r: roleAll) {
            vo = RoleVo.builder().value(Integer.toString(r.roleId))
                    .title(r.roleName).build();
            // 判断该用户是否拥有
            if (roleHaveMap.containsKey(r.roleId)){
                vo.setChecked(true);
            }
            roleVos.add(vo);
        }
        return roleVos;
    }
}
